<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

    <!-- Window -->
    <!-- https://developer.mozilla.org/zh-CN/docs/Web/API/Window -->
    <!-- window 对象表示一个包含DOM文档的窗口，其 document 属性指向窗口中载入的 DOM文档 。使用 document.defaultView 属性可以获取指定文档所在窗口。 -->
    <!-- window作为全局变量，代表了脚本正在运行的窗口，暴露给 Javascript 代码。 -->


    <p>defaultStatus status</p>
    <!-- Window.defaultStatus -->
    <!-- https://developer.mozilla.org/zh-CN/docs/Web/API/Window/defaultStatus -->
    <!-- 已废弃 Gecko 23 (Firefox 23 / Thunderbird 23 / SeaMonkey 2.20) -->
    <!-- 获取或设置给定窗口的状态栏文本。 -->
    <!-- Window.status -->
    <!-- https://developer.mozilla.org/en-US/docs/Web/API/Window/status -->
    <!-- Deprecated: This feature is no longer recommended. -->
    <!-- Window.statusbar -->
    <!-- https://developer.mozilla.org/en-US/docs/Web/API/Window/statusbar -->
    <!-- The Window.statusbar property returns the statusbar object, whose visibility can be toggled in the window. -->
    <script>
        // changing bar states on the existing window
        if (typeof netscape != 'undefined') {
            netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserWrite");
        }
        window.statusbar.visible = !window.statusbar.visible;
    </script>
    <div>
        <button onclick="setStatus();">defaultStatus status</button>
    </div>
    <script>
        function setStatus() {
            window.defaultStatus = 'Hello! ' + new Date();
            console.log('window.defaultStatus = ' + window.defaultStatus);
            console.log('window.status = ' + window.status);
        }
    </script>
    <hr>

    <p>document</p>
    <!-- window.document -->
    <!-- https://developer.mozilla.org/zh-CN/docs/Web/API/Window/document -->
    <!-- window.document返回当前窗口内的文档节点（document） -->
    <div>
        <button onclick="getDocument();">document</button>
    </div>
    <script>
        function getDocument() {
            console.log('window.document = ' + window.document);
        }
    </script>
    <hr>


    <p>frames</p>
    <!-- Window.frames -->
    <!-- https://developer.mozilla.org/zh-CN/docs/Web/API/Window/frames -->
    <!-- 返回当前窗口，一个类数组对象，列出了当前窗口的所有直接子窗口。 -->
    <script>
        console.log('window.frames.length = ' + window.frames.length);
    </script>
    <div>
        <iframe src="" frameborder="0" style="background-color: red;"></iframe>
        <iframe src="" frameborder="0" style="background-color: green;"></iframe>
        <iframe src="" frameborder="0" style="background-color: blue;"></iframe>
    </div>
    <script>
        console.log('window.frames.length = ' + window.frames.length);
    </script>
    <hr>

    <p>name</p>
    <!-- Window.name -->
    <!-- https://developer.mozilla.org/zh-CN/docs/Web/API/Window/name -->
    <!-- 获取/设置窗口的名称。 -->
    <div>
        <button onclick="openNewWindow();">name</button>
    </div>
    <script>
        function openNewWindow() {
            window.open('test.html', 'test_page', ' menubar=yes, location=yes, resizable=yes, scrollbars=yes, status=yes');
        }
    </script>
    <hr>

    <p>self top</p>
    <!-- Window.self -->
    <!-- https://developer.mozilla.org/zh-CN/docs/Web/API/Window/self -->
    <!-- 返回一个指向当前 window 对象的引用。 -->
    <!-- Window.top -->
    <!-- https://developer.mozilla.org/zh-CN/docs/Web/API/Window/top -->
    <!-- 返回窗口层级最顶层窗口的引用。 -->
    <script>
        window.name = 'main_page';
    </script>
    <div>
        <iframe src="iframe_test.html" frameborder="0" style="background-color: orange;"></iframe>
    </div>
    <hr>

    <hr style="border: red 2px solid;">

    <p>Window.open() Window.close()</p>
    <!-- https://developer.mozilla.org/zh-CN/docs/Web/API/Window/open -->
    <!-- Window 接口的 open() 方法，是用指定的名称将指定的资源加载到浏览器上下文（窗口 window ，内嵌框架 iframe 或者标签 tab ）。如果没有指定名称，则一个新的窗口会被打开并且指定的资源会被加载进这个窗口的浏览器上下文中。 -->
    <!-- Window.close() -->
    <!-- Window.close() 方法关闭当前窗口或某个指定的窗口。 -->
    <!-- 该方法只能由 Window.open() 方法打开的窗口的 window 对象来调用。 -->
    <!-- 对于由 HTMLIFrame​Element​.content​Window 返回的 Window 对象，close() 也没有效果。 -->
    <div>
        <button onclick="baiduWindow = openWindow('https://www.baidu.com', '_self');">在当前窗口打开百度</button>
        <br>
        <button onclick="baiduWindow = openWindow('https://www.baidu.com', '我的百度');">在新窗口打开百度</button>
        <button onclick="closeWindow(baiduWindow);">关闭百度窗口</button>
        <br>
        <button onclick="openSiteWithHistory();">在新窗口依次打开4个url，验证history</button>
        <button onclick="closeWindow(taskHistoryWindow);">关闭history测试窗口</button>
        <br>
        <button onclick="iframeWindow = openWindow('iframe_test.html', 'test_iframe');">在iframe打开测试页</button>
        <button onclick="closeWindow(iframeWindow);">关闭iframe（无效）</button>
        <iframe id="test_iframe" name="test_iframe" src="" frameborder="0" style="background-color: orange;"></iframe>
    </div>
    <script>
        var baiduWindow = null;
        var taskHistoryWindow = null;
        var iframeWindow = null;
        /**
         * 打开指定url
         **/
        function openWindow(url, name) {
            // return window.open(url, name, 'menubar=yes, location=yes, resizable=yes, scrollbars=yes, status=yes', true);
            return window.open(url, name, undefined, true);
        }
        /**
         * 关闭指定window
         **/
        function closeWindow(someWindow) {
            if (someWindow) {
                someWindow.close();
                someWindow = null;
            }
        }
        /**
         * 验证window.open()方法的第4个参数replace。
         * 经验证发现，只有chromium内核的浏览器支持history路径添加，而IE、Firefox、Opera不支持，特别的chromium也不支持。
         * ------------------------------------------------------
         * 本测试通过5个定时任务验证open方法的第4个参数的有效性。
         * 4个测试样本分别是：baidu、alibaba、qq、163、sina，由于将qq的第4个参数replace设置为true，其它样本的replace为false，
         * 所以新窗口的期望history路径是：baidu->qq->163->sina。
         * ------------------------------------------------------
         * 实际验证结果与期望不一致：
         * 1. 如果打开的url跨域，那么无论replace是什么，总是会在history路径中添加当前url。
         * 2. 如果打开的url是当前域，那么无论replace是什么，
         * 2.1. 如果前后2个url不相同，那么会在history路径中添加当前url。
         * 2.2. 如果前后2个url相同，那么不会在history路径中重新添加当前url。
         * ------------------------------------------------------
         * 由上所知，上面元素的期望不成立，下面的注释中的history期望路径的推断不成立。请忽略。
         **/
        function openSiteWithHistory() {
            // 自定义4个窗口打开任务的属性
            var name = 'test';
            var specs = 'menubar=yes, location=yes, resizable=yes, scrollbars=yes, status=yes';
            var tasks = [
                {
                    // url: 'https://www.baidu.com', // history: baidu
                    url: 'iframe_test.html', // history: iframe_test
                    name: name,
                    specs: specs,
                    // replace: false, // URL 在浏览历史中创建新的条目。此时history：baidu
                },
                {
                    // url: 'https://www.alibabagroup.com/cn/global/home', // history: baidu -> alibabagroup
                    url: 'test.html', // history: iframe_test -> test.html
                    name: name,
                    specs: specs,
                    // replace: false, // URL 在浏览历史中创建新的条目。此时history：baidu->alibaba
                },
                {
                    // url: 'https://www.qq.com/', // history: baidu -> alibabagroup -> qq
                    url: 'test.html', // history: iframe_test -> test.html
                    name: name,
                    specs: specs,
                    // replace: true, // URL 替换浏览历史中的当前条目。此时history：替换alibaba，baidu->qq
                },
                {
                    // url: 'https://www.163.com/', // history: baidu -> alibabagroup -> qq -> 163
                    url: 'iframe_test.html', // history: iframe_test -> test.html -> iframe_test.html
                    name: name,
                    specs: specs,
                    // replace: false, // URL 在浏览历史中创建新的条目。此时history：baidu->qq->163
                },
                {
                    // url: 'https://www.sina.com/', // history: baidu -> alibabagroup -> qq -> 163 -> sina
                    url: 'test.html', // history: iframe_test -> test.html -> iframe_test.html -> test.html
                    name: name,
                    specs: specs,
                    // replace: false, // URL 在浏览历史中创建新的条目。此时history：baidu->qq->163->sina
                },
            ];
            var time = 0;
            tasks.forEach(function (task) {
                // task.url='test.html';
                // task.url='https://www.baidu.com';
                task.replace = false;
                setTimeout(function () {
                    taskHistoryWindow = window.open(task.url, task.name, task.specs, task.replace);
                    // taskHistoryWindow = window.open(task.url, task.name, task.specs);
                    console.log('open ' + JSON.stringify(task));
                }, time);
                time += 2000;
            });

        }
    </script>
    <hr>

    <p>window.alert</p>
    <!-- https://developer.mozilla.org/zh-CN/docs/Web/API/Window/alert -->
    <!-- 显示一个警告对话框,上面显示有指定的文本内容以及一个"确定"按钮。 -->
    <div>
        <button onclick="showAlert();">对话框</button>
    </div>
    <script>
        function showAlert() {
            window.alert("Hello world!");
        }
    </script>
    <hr>


    <p>window.setTimeout</p>
    <p>https://developer.mozilla.org/zh-CN/docs/Web/API/setTimeout</p>
    <p> WindowOrWorkerGlobalScope 混合的 setTimeout()方法设置一个定时器，该定时器在定时器到期后执行一个函数或指定的一段代码。</p>
    <p>WindowOrWorkerGlobalScope.clearTimeout()</p>
    <p>WindowOrWorkerGlobalScope内置的clearTimeout()方法取消了先前通过调用setTimeout()建立的定时器。</p>
    <div>
        <button onclick="showTimeDelay();">5秒后显示当前时间</button>
        <button onclick="cancelShowTimeDelay();">取消显示当前时间</button>
    </div>
    <script>
        var timeoutID = undefined;
        function showTimeDelay() {
            timeoutID = setTimeout(function () {
                alert(new Date().toUTCString());
            }, 5000);
            // 注：课本上用了一个调用函数的字符串表达式代替function
            // time：ms毫秒
        }
        function cancelShowTimeDelay() {
            if (timeoutID == undefined || timeoutID == null) {
                return;
            }
            clearTimeout(timeoutID);
            taskId = undefined;
        }
    </script>





</body>

</html>